#pragma once

#include <memory>
#include "Epoller.hpp"
#include "Socket.hpp"

using namespace NetWorkModule;
using namespace EpollerModule;

const static uint16_t defaultport = 8088;
const static int gbacklog = 8; // 维护的全连接队列

class EpollServer
{
    const int defaultsockfd = -1;
    const static int maxevents = 64;
public:
    EpollServer(uint16_t port = defaultport): 
    _listensock(new TcpSocket()),
    _port(port), 
    _isrunning(false), 
    _epoller(std::make_unique<Epoller>())
    {}
    bool Initserver()
    {
        // 创建监听套接字
        _listensock->BuildListenSocketMethod(_port, gbacklog);
        lg.LogMessage(Info, "init listen sock success, listensockfd is: %d", _listensock->GetSockFd());
        // 创建epoll模型
        _epoller->InitEpoller();
        lg.LogMessage(Info, "init listen epoll success");
        // 将监听套接字的读事件添加到epoll模型
        _epoller->AddEvent(_listensock->GetSockFd(), EPOLLIN);
        return true;
    }
    void Loop()
    {
        _isrunning = true;
        while(_isrunning)
        {
            // epoll负责等待事件就绪
            int n = _epoller->Wait(_recvs, maxevents, 1000);
            switch(n)
            {
            case 0:
                lg.LogMessage(Debug, "timeout...");
                break;
            case -1:
                lg.LogMessage(Error, "wait epoll failed");
                break;
            default:
                // 事件就绪
                lg.LogMessage(Info, "event happened");
                break;
            }
        }
        _isrunning = false;

    }
    ~EpollServer()
    {}
private:
    std::unique_ptr<Socket> _listensock;
    std::unique_ptr<Epoller> _epoller;
    uint16_t _port;
    bool _isrunning;
    struct epoll_event _recvs[maxevents];
};